-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rest server #839
Rest server #839
Changes from 110 commits
26da86d
b47eb05
f8b28c3
a4f0793
ff95dda
9110fe9
28a64b6
8ab3ce5
fac1217
9a04a55
bfbecd6
bb4f4da
89ffcd8
ea8b90d
28c8bc3
0a26c15
3e60b80
ee36f48
33b010f
6f8eefc
ae89734
0382984
5a97e6b
21bc035
8745fd7
92e01d3
a2853ed
c5382ff
f5c97ee
459e7cb
5ca3ca1
50f409d
162b036
96a5536
66d2239
333e09c
4964664
7959bca
cc9493f
ec1bb83
e29b213
ac0ddc2
bf4fca7
6f62641
370e855
5cfd7f8
6651d32
654ef49
efa90bb
f281516
2c0391d
ef1f3db
e6e9aac
f6e1249
0e32449
bc6f89e
2c18b6d
61f53cb
3679add
1eefc6c
46bc7c7
e68a7fd
ee26faf
475b4fe
79176e3
287cf07
b2dbc9e
ce61674
8fbe605
d1bcc57
77a2a7a
117b1bb
4d817cf
27a7592
22ad417
decd24a
73276da
8c2e23f
459938f
6b82940
e6f3215
76194d7
784c7db
35741f6
8c588bb
f46ddbf
a072dc1
8c06289
26170fc
10c6655
b9613a9
c60c7a7
1076496
c5aeee4
a5a968b
668feb3
c5c2f5c
68c4dfe
e915ad0
10de333
87949e7
16c669e
35ff01b
3971f5f
a8d378a
2beb17e
aded6ed
26d0b17
724b10b
6cbea40
0c96908
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
## RestServer Plugin | ||
In this section of you will learn how to make a `neo-cli` plugin that integrates with `RestServer` | ||
plugin. Lets take a look at [Example Plugin](/examples/RestServerPlugin). | ||
|
||
- No reference to `RestServer` is required. | ||
- Requires DotNet 7.0 | ||
|
||
## Folder Structure | ||
```bash | ||
Project | ||
├── Controllers | ||
│ └── ExampleController.cs | ||
├── ExamplePlugin.cs | ||
├── ExamplePlugin.csproj | ||
├── Exceptions | ||
│ └── CustomException.cs | ||
└── Models | ||
└── ErrorModel.cs | ||
``` | ||
The only thing that is important here is the `controllers` folder. This folder is required for the `RestServer` | ||
plugin to register the controllers in its web server. This location is where you put all your controllers. | ||
|
||
## Controllers | ||
The `controller` class is the same as ASP.Net Core's. Controllers must have their attribute set | ||
as `[ApiController]` and inherent from `ControllerBase`. | ||
|
||
## Swagger Controller | ||
A `Swagger` controller uses special attributes that are set on your controller's class. | ||
|
||
**Controller Class Attributes** | ||
- `[Produces(MediaTypeNames.Application.Json)]` (_Required_) | ||
- `[Consumes(MediaTypeNames.Application.Json)]` (_Required_) | ||
- `[ApiExplorerSettings(GroupName = "v1")]` | ||
- **GroupName** - _is which version of the API you are targeting._ | ||
- `[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ErrorModel))]` (_Required_) | ||
- **Type** - _Must have a base class of [error](#error-class)._ | ||
|
||
## Error Class | ||
Needs to be the same as `RestServer` of else there will be some inconsistencies | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/ |
||
with end users not knowing which type to use. This class can be `public` or `internal`. | ||
Properties `Code`, `Name` and `Message` values can be whatever you desire. | ||
|
||
**Model** | ||
```csharp | ||
public class ErrorModel | ||
{ | ||
public int Code { get; set; }; | ||
public string Name { get; set; }; | ||
public string Message { get; set; }; | ||
} | ||
Comment on lines
+41
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The case is they can't. We have neo-project/proposals#156 for RPC errors, and if we're merging this PR, then I think we need some unified set of error codes for REST as far. |
||
``` | ||
|
||
## Controller Actions | ||
Controller actions need to have special attributes as well as code comments. | ||
|
||
- `[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))]` | ||
|
||
HTTP status code `200 (OK)` is required with return type defined. You can use more than one attribute. One per HTTP status code. | ||
|
||
### Action Example | ||
```csharp | ||
[HttpGet("contracts/{hash:required}/sayHello", Name = "GetSayHello")] | ||
[ProducesResponseType(StatusCodes.Status204NoContent)] | ||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string))] | ||
public IActionResult GetSayHello( | ||
[FromRoute(Name = "hash")] | ||
UInt160 scripthash) | ||
{ | ||
if (scripthash == UInt160.Zero) | ||
return NoContent(); | ||
return Ok($"Hello, {scripthash}"); | ||
} | ||
``` | ||
Notice that the _above_ example also returns with HTTP status code of `204 No Content`. | ||
This action `route` also extends the `contracts` API. Adding method `sayHello`. Routes | ||
can be what you like as well. But if you want to extend on any existing controller you | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/extend on/extend |
||
must use existing routes paths. | ||
|
||
### Path(s) | ||
- `/api/v1/contracts/` | ||
- `/api/v1/ledger/` | ||
- `/api/v1/node/` | ||
- `/api/v1/tokens` | ||
- `/api/v1/Utils/` | ||
|
||
### Excluded Path(s) | ||
- `/api/v1/wallet/` | ||
|
||
_for security reasons_. | ||
|
||
### Code Comments for Swagger | ||
```csharp | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/// <param name="" example=""></param> | ||
/// <returns></returns> | ||
/// <response code="200">Successful</response> | ||
/// <response code="400">An error occurred. See Response for details.</response> | ||
``` | ||
|
||
Also note that you need to have `GenerateDocumentationFile` enabled in your | ||
`.csproj` file. The `xml` file that is generated; in our case would be `RestServerPlugin.xml`. | ||
This file gets put in same directory `Plugins/RestServerPlugin/` which is in the root of `neo-node` | ||
executable folder. Where you will see `neo-cli.exe`. | ||
|
||
File `RestServerPlugin.xml` will get added to `Swagger` automatically by the `RestServer` | ||
plugin. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
## Table | ||
|
||
| Name | Type | Description | | ||
| :--- | :---: | :--- | | ||
|**Network**|_uint32_|_Network you would like the `RestServer` to be enabled on._| | ||
|**BindAddress**|_string_|_Ip address of the interface you want to bind too._| | ||
|**Port**|_uint32_|_Port number to bind too._| | ||
|**KeepAliveTimeout**|_uint32_|_Time to keep the request alive, in seconds._| | ||
|**SslCertFile**|_string_|_Is the path and file name of a certificate file, relative to the directory that contains the node's executable files._| | ||
|**SslCertPassword**|_string_|_Is the password required to access the `X.509` certificate data._| | ||
|**TrustedAuthorities**|_StringArray_|_Tumbprints of the of the last certificate authority in the chain._| | ||
|**EnableBasicAuthentication**|_boolean_|_enables basic authentication._| | ||
|**RestUser**|_string_|_Basic authentication's `username`._| | ||
|**RestPass**|_string_|_Basic authentication's `password`._| | ||
|**EnableCors**|_boolean_|_Enables Cross-origin resource sharing (`CORS`). Note by default it enables `*` any origin._| | ||
|**AllowOrigins**|_StringArray_|_A list of the origins to allow. Note needs to add origins for basic auth to work with `CORS`._| | ||
|**DisableControllers**|_StringArray_|_A list of `controllers` to be disabled. Requires restart of the node, if changed._| | ||
|**EnableCompression**|_boolean_|_Enables `GZip` data compression._| | ||
|**CompressionLevel**|_enum_|_Compression level. Values can be `Fastest`, `Optimal`, `NoCompression` or `SmallestSize`_| | ||
|**EnableForwardedHeaders**|_boolean_|_Enables response/request headers for proxy forwarding. (data center usage)_| | ||
|**EnableSwagger**|_boolean_|_Enables `Swagger` with `Swagger UI` for the rest services._| | ||
|**MaxPageSize**|_uint32_|_Max page size for searches on `Ledger`/`Contracts` route._| | ||
|**MaxConcurrentConnections**|_int64_|_Max allow concurrent HTTP connections._| | ||
|**MaxInvokeGas**|_int64_|_Max gas to be invoked on the `Neo` virtual machine._| | ||
|
||
## Default "Config.json" file | ||
```json | ||
{ | ||
"PluginConfiguration": { | ||
"Network": 860833102, | ||
"BindAddress": "127.0.0.1", | ||
"Port": 10339, | ||
"KeepAliveTimeout": 120, | ||
"SslCertFile": "", | ||
"SslCertPassword": "", | ||
"TrustedAuthorities": [], | ||
"EnableBasicAuthentication": false, | ||
"RestUser": "", | ||
"RestPass": "", | ||
"EnableCors": true, | ||
"AllowOrigins": [], | ||
"DisableControllers": [ "WalletController" ], | ||
"EnableCompression": true, | ||
"CompressionLevel": "SmallestSize", | ||
"EnableForwardedHeaders": false, | ||
"EnableSwagger": true, | ||
"MaxPageSize": 50, | ||
"MaxConcurrentConnections": 40, | ||
"MaxTransactionFee": 10000000, | ||
"MaxInvokeGas": 20000000, | ||
"WalletSessionTimeout": 120 | ||
} | ||
} | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
## RestServer | ||
In this section you will learn about `RestServer` plugin and how it works. | ||
|
||
See [config.json](ConfigFile.md) for information about the configurations. | ||
|
||
## Dependencies | ||
- **Microsoft.AspNetCore.JsonPatch.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.NewtonsoftJson.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.Versioning.dll** `Required` | ||
- **Microsoft.OpenApi.dll** `Required` | ||
- **Newtonsoft.Json.Bson.dll** `Required` | ||
- **Newtonsoft.Json.dll** `Required` | ||
- **System.ServiceProcess.ServiceController.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.Versioning.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.Versioning.dll** `Required` | ||
- **Microsoft.AspNetCore.Mvc.Versioning.dll** `Required` | ||
- **Microsoft.OpenApi.dll** `Swagger` | ||
- **Swashbuckle.AspNetCore.Swagger.dll** `Swagger` | ||
- **Swashbuckle.AspNetCore.SwaggerGen.dll** `Swagger` | ||
- **Swashbuckle.AspNetCore.SwaggerUI.dll** `Swagger` | ||
- **Swashbuckle.AspNetCore.Newtonsoft.dll** `Swagger` | ||
- **RestServer.xml** `Swagger UI` | ||
|
||
These files go in the same directory as the `RestServer.dll`. In neo-cli | ||
`plugins/RestServer/` folder. | ||
|
||
## Response Headers | ||
| Name | Value(s) | Description | | ||
| :---: | --- | :--- | | ||
|**server**|_neo-cli/3.6.0 RestServer/3.6.0_|_`neo-cli` and `RestServer` version._| | ||
|
||
Custom headers can be added by [Neo RestServer Plugins](Addons.md). | ||
|
||
## JSON Serializer | ||
`RestServer` uses custom NewtonSoft JSON Converters to serialize controller action | ||
responses and `route` parameters. | ||
|
||
**One Way Binding** - `Write` only. | ||
- `Neo.SmartContract.ContractState` | ||
- `Neo.SmartContract.NefFile` | ||
- `Neo.SmartContract.MethodToken` | ||
- `Neo.SmartContract.Native.TrimmedBlock` | ||
- `Neo.SmartContract.Manifest.ContractAbi` | ||
- `Neo.SmartContract.Manifest.ContractGroup` | ||
- `Neo.SmartContract.Manifest.ContractManifest` | ||
- `Neo.SmartContract.Manifest.ContractPermission` | ||
- `Neo.SmartContract.Manifest.ContractPermissionDescriptor` | ||
- `Neo.Network.P2P.Payloads.Block` | ||
- `Neo.Network.P2P.Payloads.Header` | ||
- `Neo.Network.P2P.Payloads.Signer` | ||
- `Neo.Network.P2P.Payloads.TransactionAttribute` | ||
- `Neo.Network.P2P.Payloads.Transaction` | ||
- `Neo.Network.P2P.Payloads.Witness` | ||
|
||
**Two Way Binding** - `Read` & `Write` | ||
- `System.Guid` | ||
- `System.ReadOnlyMemory<T>` | ||
- `Neo.BigDecimal` | ||
- `Neo.UInt160` | ||
- `Neo.UInt256` | ||
- `Neo.Cryptography.ECC.ECPoint` | ||
- `Neo.VM.Types.Array` | ||
- `Neo.VM.Types.Boolean` | ||
- `Neo.VM.Types.Buffer` | ||
- `Neo.VM.Types.ByteString` | ||
- `Neo.VM.Types.Integer` | ||
- `Neo.VM.Types.InteropInterface` | ||
- `Neo.VM.Types.Null` | ||
- `Neo.VM.Types.Map` | ||
- `Neo.VM.Types.Pointer` | ||
- `Neo.VM.Types.StackItem` | ||
- `Neo.VM.Types.Struct` | ||
|
||
## Remote Endpoints | ||
Parametes `{hash}` can be any Neo N3 address or scripthash; `{address}` can be any Neo N3 address **only**; `{number}` and `{index}` can be any _**uint32**_. | ||
|
||
**Parameter Examples** | ||
- `{hash}` - _0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5_ **or** _NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc_ | ||
- `{address}` - _NiHURyS83nX2mpxtA7xq84cGxVbHojj5Wc_ | ||
- `{number}` - _1_ | ||
- `{index}` - _2500000_ | ||
|
||
**Paths** | ||
- Utils | ||
- `[GET]` `/api/v1/utils/{hash}/address` | ||
- `[GET]` `/api/v1/utils/{address}/scripthash` | ||
- `[GET]` `/api/v1/utils/{hash}/{address}/validate` | ||
- Node | ||
- `[GET]` `/api/v1/node/peers` | ||
- `[GET]` `/api/v1/node/plugins` | ||
- `[GET]` `/api/v1/node/settings` | ||
- Ledger | ||
- `[GET]` `/api/v1/ledger/neo/accounts` | ||
- `[GET]` `/api/v1/ledger/gas/accounts` | ||
- `[GET]` `/api/v1/ledger/blocks?page={number}&size={number}` | ||
- `[GET]` `/api/v1/ledger/blocks/height` | ||
- `[GET]` `/api/v1/ledger/blocks/{index}` | ||
- `[GET]` `/api/v1/ledger/blocks/{index}/header` | ||
- `[GET]` `/api/v1/ledger/blocks/{index}/witness` | ||
- `[GET]` `/api/v1/ledger/blocks/{index}/transactions?page={number}&size={number}` | ||
- `[GET]` `/api/v1/ledger/transactions/{hash}` | ||
- `[GET]` `/api/v1/ledger/transactions/{hash}/witnesses` | ||
- `[GET]` `/api/v1/ledger/transactions/{hash}/signers` | ||
- `[GET]` `/api/v1/ledger/transactions/{hash}/atributes` | ||
- `[GET]` `/api/v1/ledger/memorypool?page={number}&size={number}` | ||
- `[GET]` `/api/v1/ledger/memorypool/verified?page={number}&size={number}` | ||
- `[GET]` `/api/v1/ledger/memorypool/unverified?page={number}&size={number}` | ||
- `[GET]` `/api/v1/ledger/memorypool/count` | ||
- Tokens | ||
- `[GET]` `/api/v1/tokens/balanceof/{address}` | ||
- NFTs | ||
- `[GET]` `/api/v1/tokens/nep-11?page={number}&size={number}` | ||
- `[GET]` `/api/v1/tokens/nep-11/count` | ||
- `[GET]` `/api/v1/tokens/nep-11/{hash}/balanceof/{address}` | ||
- NEP-17 | ||
- `[GET]` `/api/v1/tokens/nep-17?page={number}&size={number}` | ||
- `[GET]` `/api/v1/tokens/nep-17/count` | ||
- `[GET]` `/api/v1/tokens/nep-17/{hash}/balanceof/{address}` | ||
- Contracts | ||
- `[GET]` `/api/v1/contracts?page={number}&size={number}` | ||
- `[GET]` `/api/v1/contracts/count` | ||
- `[GET]` `/api/v1/contracts/{hash}` | ||
- `[GET]` `/api/v1/contracts/{hash}/abi` | ||
- `[GET]` `/api/v1/contracts/{hash}/manifest` | ||
- `[GET]` `/api/v1/contracts/{hash}/nef` | ||
- `[GET]` `/api/v1/contracts/{hash}/storage` | ||
- Wallet | ||
- `[POST]` `/api/v1/wallet/open` | ||
- `[POST]` `/api/v1/wallet/create` | ||
- `[POST]` `/api/v1/wallet/{session}/address/create` | ||
- `[GET]` `/api/v1/wallet/{session}/address/list` | ||
- `[GET]` `/api/v1/wallet/{session}/asset/list` | ||
- `[GET]` `/api/v1/wallet/{session}/balance/list` | ||
- `[POST]` `/api/v1/wallet/{session}/changepassword` | ||
- `[GET]` `/api/v1/wallet/{session}/close` | ||
- `[GET]` `/api/v1/wallet/{session}/delete/{address}` | ||
- `[GET]` `/api/v1/wallet/{session}/export/{address}` | ||
- `[GET]` `/api/v1/wallet/{session}/export` | ||
- `[GET]` `/api/v1/wallet/{session}/gas/unclaimed` | ||
- `[GET]` `/api/v1/wallet/{session}/key/list` | ||
- `[POST]` `/api/v1/wallet/{session}/import` | ||
- `[POST]` `/api/v1/wallet/{session}/import/multisigaddress` | ||
- `[POST]` `/api/v1/wallet/{session}/transfer` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still have an example? Because currently an example plugin link navigates to nowhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a start https://github.com/cschuchardt88/neo-modules/blob/RestServer/docs/RestServer/Addons.md however looks like some stuff is missing.